package config

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"strconv"
	"time"

	"gopkg.in/yaml.v3"
)

type Conf struct {
	Config Config
}

type Config struct {
	Scanners      []Scanner
	Url           string
	AppID         string
	MetricContent MetricContent
}

type Scanner struct {
	Action string
	Target string
	Cron   string
	Name   string
}

type MetricContent struct {
	Indicators    Indicators
	PerformanceID string
	Resource      Resource
}

type Indicators struct {
	Indicator []Indicator
	Time      Time
}

type Indicator struct {
	Content                   string             `json:"content"`
	IndicatorDenominatorUnit  *string            `json:"indicatorDenominatorUnit,omitempty"`
	IndicatorDenominatorValue *string            `json:"indicatorDenominatorValue,omitempty"`
	IndicatorDimension        IndicatorDimension `json:"indicatorDimension"`
	IndicatorLevel            string             `json:"indicatorLevel"`
	IndicatorNumber           string             `json:"indicatorNumber"`
	IndicatorNumeratorUnit    *string            `json:"indicatorNumeratorUnit,omitempty"`
	IndicatorNumeratorValue   *string            `json:"indicatorNumeratorValue,omitempty"`
	IndicatorObject           string             `json:"indicatorObject"`
	IndicatorSubObject        *string            `json:"indicatorSubObject,omitempty"`
	IndicatorUnit             string             `json:"indicatorUnit"`
	IndicatorValue            string             `json:"indicatorValue"`
}

type IndicatorDimension struct {
	Type string `json:"type"`
}

type Time struct {
	BeginTime       string `json:"beginTime"`
	EndTime         string `json:"endTime"`
	StatisticPeriod int64  `json:"statisticPeriod"`
}

type Resource struct {
	BusinessPlatform string
	HostIP           string
	HostName         string
	ProductName      string
}

func GetConfig() Conf {
	var conf Conf
	fileData, err := ioutil.ReadFile("../etc/config.yaml")
	if err != nil {
		fmt.Println(err.Error())
	}

	err = yaml.Unmarshal(fileData, &conf)
	if err != nil {
		fmt.Println(err.Error())
	}
	fmt.Println(conf)
	return conf
}

func (metric MetricContent) GetMetricContent(conf Config, addr string, isAlive bool) MetricContent {
	metric.PerformanceID = RandString(16)
	metric.Indicators.Time.BeginTime = time.Now().Format("2006-01-02 15:04:05")
	metric.Indicators.Time.EndTime = time.Now().Add(time.Minute).Format("2006-01-02 15:04:05")
	if len(metric.Indicators.Indicator) > 0 {
		metric.Indicators.Indicator[0].Content = getContent(conf, addr)
		metric.Indicators.Indicator[0].IndicatorValue = strconv.FormatBool(isAlive)
	}
	return metric
}

func RandString(len int) string {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	bytes := make([]byte, len)
	for i := 0; i < len; i++ {
		b := r.Intn(26) + 65
		bytes[i] = byte(b)
	}
	return string(bytes)
}

func getContent(conf Config, addr string) string {
	content := ""
	for _, v := range conf.Scanners {
		if v.Target == addr {
			content = v.Name
		}
	}
	return content
}
